import {PlButton, PlForm, PlFormItem, PlImageUploader, PlInput, useDialog} from "plain-design";
import React from "react";
import {defer, reactive, useRefs} from "plain-design-composition";
import {MonacaEditor} from "@/components/monaco/MonacoEditor";
import {deepcopy} from "plain-utils/object/deepcopy";
import {DialogServiceFormatOption} from "plain-design/src/packages/useDialog";

interface iUserInfo {
    author?: string,
    avatarId?: string,
    avatar?: string,
}

interface iSolutionInfo extends iUserInfo {
    content: string
}

const UserInfoCache = (() => {

    const CACHE_KEY = '@@SOLUTION_USER_INFO'

    const get = (): null | iUserInfo => {
        const cacheString = window.localStorage.getItem(CACHE_KEY)
        return !cacheString ? null : JSON.parse(cacheString)
    }

    const set = (userInfo: iUserInfo) => {
        state.userInfo = userInfo
        window.localStorage.setItem(CACHE_KEY, JSON.stringify(userInfo))
    }

    const state = reactive({
        userInfo: get(),
    })

    return {state, update: set}
})()

export function useSolution() {

    const $dialog = useDialog()

    const {refs, onRef} = useRefs({form: PlForm})

    const uploadConfig = {
        action: 'http://1.116.13.72:7001/saveFile',
        filename: 'file',
        data: {
            module: 'exercise_author_avatar',
        },
    }

    const state = reactive({
        formData: {} as iSolutionInfo
    })

    const edit = async (initialValue: any, beforeConfirm: (data: iSolutionInfo) => any) => {
        const dfd = defer<iSolutionInfo>()
        const {author, avatar, avatarId} = UserInfoCache.state.userInfo || {}

        state.formData = {
            author, avatar, avatarId,
            ...deepcopy(initialValue),
        }

        const handler = {
            onConfirm: async () => {
                UserInfoCache.update(state.formData)
                await refs.form?.validate()
                await beforeConfirm(state.formData)
                dialogOption.close()
                dfd.resolve(state.formData)
            },
            onCancel: () => {
                dfd.reject('cancel')
                dialogOption.close();
            },
            onUploadSuccess: ({data}: any) => {
                state.formData.avatarId = data.id
                state.formData.avatar = data.path
            },
        }
        const dialogOption: DialogServiceFormatOption = {
            title: '提交答案',
            status: null,
            dialogProps: {
                horizontal: 'end',
                wrapperPadding: false,
                fullHeight: true,
                transition: 'pl-transition-dialog-right',
                cancelOnClickMask: false,
            },
            render: () => <>
                <PlForm ref={onRef.form} modelValue={state.formData}>
                    <PlFormItem label="昵称" required field="author">
                        <PlInput v-model={state.formData.author}/>
                    </PlFormItem>
                    <PlFormItem label="头像">
                        <PlImageUploader urlPrefix={"http://1.116.13.72/"} v-model={state.formData.avatar} uploadConfig={uploadConfig} onUploadSuccess={handler.onUploadSuccess}/>
                    </PlFormItem>
                    <PlFormItem label="答案" required field="content">
                        <span>(markdown)</span>
                    </PlFormItem>
                    <div style={{height: '300px', overflow: 'hidden', marginBottom: '20px'}}>
                        <MonacaEditor v-model={state.formData.content} language="markdown" theme="vs-dark"/>
                    </div>
                    <div style={{display: 'flex'}}>
                        <PlButton label="提交" size="large" onClick={handler.onConfirm} style={{flex: 1, marginRight: '8px'}}/>
                        <PlButton label="取消" size="large" mode="stroke" onClick={handler.onCancel} style={{flex: 1}}/>
                    </div>
                </PlForm>
            </>,
            onCancel: handler.onCancel,
        } as any
        $dialog(dialogOption)

        return dfd.promise
    }

    return {edit}
}
